// 生成数独解决方案
import Toolkit from './toolkit';

// const Toolkit = require('./toolkit');

export class Generator {
    matrix: number[][];
    orders: number[][];

// module.exports = class Generator {
    generate(): void {
        while (!this.internalgenerate()) {
            console.log('try again')
        }
    }

    internalgenerate() {
        // 入口解决方案
        // 先生成矩阵
        this.matrix = Toolkit.matrix.makeMatrix();
        this.orders = Toolkit.matrix.makeMatrix()
            .map(row => row.map((v, i) => i))
            .map(row => Toolkit.matrix.shuffle(row));       //将顺序打乱

        // Toolkit.matrix.makeRow()
        //   .every((n))
        for (let n = 1; n <= 9; n++) {
            if (!this.fillNumber(n)) {
                return false;
            }

        }
        return true
    }

    private fillNumber(n: number) {
        // 填数操作
        // 填入行数据
        return this.fillRow(n, 0);
    }

    private fillRow(n: number, rowIndex: number) {
        // 填入行 结束
        if (rowIndex > 8) {
            return true
        }
        const row = this.matrix[rowIndex];
        // 随机选择列
        const orders = this.orders[rowIndex];
        for (let i = 0; i < 9; i++) {
            // const colIndex = i;
            const colIndex = orders[i];
            // 当前位置已有数据
            if (row[colIndex]) {
                continue;
            }
            // 检查当前位置是否可以填 n
            if (!Toolkit.matrix.checkFillAble(this.matrix, n, rowIndex, colIndex)) {
                continue;
            }
            row[colIndex] = n;
            // 当前行填写 n 成功，递归调用 fillRow 来在下一行中填写 n
            // 去下一行提填写 n，如果没填进去，就去当前行的下一个位置填写
            if (!this.fillRow(n, rowIndex + 1)) {
                row[colIndex] = 0;
                continue;
            }
            return true;
        }
        return false;
    }
}

export default Generator;
// const generator = new Generator();
// generator.generate();
// console.log(generator.matrix)
